<?php
/**
 * Celebrio Database module
 * 
 * @copyright  Copyright (c) 2011 Celebrio Software
 * @package    Celebrio
 * @subpackage Database
 */
namespace Celebrio\Database;

use \dibi;

use Celebrio\Core\IModuleInit;

use Celebrio\Database\DatabaseInit;

use Celebrio\AccessControl\AclConstants;

use Celebrio\PasswordHasher;

/**
 * PostgreSQL initialization/installation routines.
 *
 * @author     pavel
 * @package    Kernel
 */
class PostgreInit extends DatabaseInit implements IDatabaseInit {
    
    public function init(array $settings = array()) {
        $settings["result"]["detectTypes"] = true;
        parent::init($settings);
    }

    public function install(array $configuration = array()) {
        parent::installDatabase($configuration);
    }
    
    public function isAvailable() {
        return extension_loaded("pgsql");
    }
    
    public function changeConfig(array $configuration) {
        
        $host_array = explode(":", $configuration['host']);
        $config = array (
                    "driver" => "postgre",
                      "host" => $host_array[0],
                      "user" => $configuration['username'],
                  "password" => $configuration['password'],
                    "dbname" => $configuration['database'],
                      "port" => ( count($host_array) == 2 ? $host_array[1] : "5433"),
                   "charset" => "utf8",
           "connect_timeout" => "5"
        );
        
        return $config;
    }
    
    protected function databaseExists($dbname) {
        $query = dibi::query("select count(*) from pg_catalog.pg_database where datname = %s;", $dbname );
        
        if($query->fetchSingle()==0) {
            $query->free();
            return false;
        } else {
            $query->free();
            return true;
        }
    }

    protected function tablesExist($dbname) {
        $query = dibi::query("SELECT 1
            FROM pg_tables
            WHERE schemaname='public'
            AND tablename='users'");
        if($query->fetchSingle()==0) {
            $query->free();
            return false;
        } else {
            $query->free();
            return true;
        }
    }

    public function createLogin ( $username, $pass, $newUser = true) {
        $password = PasswordHasher::databaseHash($username, $pass);
        if ($newUser) {
            if ($username === AclConstants::ROOT_USER) {
                dibi::nativeQuery("CREATE USER \"$username\" WITH CREATEUSER PASSWORD '$password';");
                dibi::nativeQuery("GRANT ALL PRIVILEGES ON SCHEMA 'public' TO PUBLIC;");
            }
            else {
                //TODO the new user should not be superuser
                dibi::nativeQuery("CREATE USER \"$username\" WITH CREATEUSER PASSWORD '$password';");
                
                //select tablename from pg_tables where schemaname='public';
                //dibi::nativeQuery("grant all on acl_log, passwords, resources, logins, roles, privileges, users_roles, users, acl, security_questions to $username;");
                //select relname from pg_class where relkind='S';
                //dibi::nativeQuery("grant all on acl_id_seq, privileges_id_seq, resources_id_seq, roles_id_seq, users_id_seq to $username;");
            }
        } else {
            //TODO vyzkouset, jestli funguje
            dibi::nativeQuery("ALTER USER \"$username\" WITH PASSWORD '$password';");
        }
    }

    public function deleteLogin ( $username ) {
        dibi::nativeQuery("DROP USER \"$username\";");
    }
    
    
    
    
    
    protected static function getDatabase(array $configuration) {
        return $configuration["dbname"];
    }
    
    protected static function setMasterDatabase(array &$configuration) {
        unset($configuration["dbname"]);
    }
    
    protected static function setDatabase(array &$configuration, $database) {
        $configuration["dbname"] = $database;
    }
    
    protected static function setUser(array &$configuration, $user) {
        $configuration["user"] = $user;
    }
    
    protected static function setPassword(array &$configuration, $password) {
        $configuration["password"] = $password;
    }

}
